﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using WCS.Infrastructure.Attr;
using WCS.Infrastructure.Dto.Response.Common;
using WCS.Infrastructure.EFCore;
using WCS.Infrastructure.Tools;
using WCS.Service.Interface;

namespace WCS.Api.Admin.Filter
{
    /// <summary>
    /// 行为日志过滤器
    /// </summary>
    public class ActionFilter : BaseFilter
    {
        private readonly ILogService _logService;


        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="userService"></param>
        /// <param name="logService"></param>
        public ActionFilter(IConfiguration configuration,
            IUserService userService,
            ILogService logService
            ) : base(configuration, userService)
        {
            _logService = logService;
        }

        /// <summary>
        /// 记录行为日志
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            OnActionExecutedAsync(context).GetAwaiter().GetResult();
        }

        /// <summary>
        /// 记录行为日志（异步实现）
        /// </summary>
        /// <param name="context"></param>
        protected async Task OnActionExecutedAsync(ActionExecutedContext context)
        {

            var result = context.Result as ObjectResult;
            if (result != null)
            {
                var result2 = result.Value as ApiResult;
                // if (result2 != null)

                // 如果不是 ApiResult 类型，为日志记录创建一个临时的 ApiResult
                if (result2 == null)
                {
                    // 为非 ApiResult 类型创建临时的日志记录对象
                    result2 = new ApiResult
                    {
                        code = ApiCode.ok, // 假设成功，因为能执行到这里说明没有异常
                        message = "第三方系统回调成功",
                        data = result.Value
                    };
                }
                else
                {

                    if (result2.data == null)
                    {
                        context.Result = new ObjectResult(new
                        {
                            code = result2.code,
                            message = result2.message
                        });
                    }
                }

                // 判断是否需要记录日志
                var action = context.ActionDescriptor as ControllerActionDescriptor;

                var user = await this.GetCurrentUser(context.HttpContext.Response.HttpContext.User.Identity?.Name);
                string? userId = context.HttpContext.GetCurrentUserId();

                var attr = action.MethodInfo.GetCustomAttribute<ActionLogAttribute>();
                if (attr != null)
                {
                    string paras = "";

                    if (context.HttpContext.Request.Method.ToUpper() == "GET")
                    {
                        var keys = context.HttpContext.Request.Query.Keys;
                        foreach (var item in keys)
                        {
                            paras += $"{item}={context.HttpContext.Request.Query[item]};";
                        }
                    }
                    else
                    {
                        var request = context.HttpContext.Request;
                        // 启动倒带方式
                        request.EnableBuffering();
                        if (request.Method.ToLower().Equals("post"))
                        {
                            request.Body.Seek(0, SeekOrigin.Begin);
                            using var reader = new StreamReader(request.Body, Encoding.UTF8);
                            // 使用异步读取
                            paras = await reader.ReadToEndAsync();
                            //paras = paras.Length > 999 ? paras.Substring(0, 999) : paras;
                        }
                    }


                    string path = _configuration["Path:Logs"];
                    string name = DateTime.Now.ToString("yyyyMMdd") + "_action" + ".txt";
                    string content = "【日志】时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n";
                    content += "地址：" + context.HttpContext.Request.Path + "\r\n";
                    content += $"分组【{attr.Group}】行为【{attr.Action}】\r\n";
                    content += $"用户【{userId}】\r\n";
                    content += $"参数【{paras}】";
                    content += $"结果【{(int)result2.code}】message【{result2.message}】 \r\n\r\n";

                    try
                    {
                        // 使用异步文件写入
                        await System.IO.File.AppendAllTextAsync(path + name, content);
                    }
                    catch (Exception)
                    {
                        // 考虑记录异常日志
                    }

                    try
                    {
                        // 需要记录日志  
                        // 记录到数据库
                        ActionLog actionlog = new ActionLog()
                        {
                            Id = Config.GUID(),
                            Action = attr.Action,
                            ApiUrl = context.HttpContext.Request.Path,
                            CreationTime = DateTime.Now,
                            Ip = Config.GetIp(),
                            Params = paras,
                            Result = (int?)result2.code,
                            ResultMessage = result2.message,
                            Type = attr.Group,
                            UserId = userId,
                            //Version = "PC",
                        };

                        await _logService.WriteAction(actionlog);
                    }
                    catch (Exception)
                    {
                        // 考虑记录异常日志
                    }
                }

            }

        }
    }
}